﻿using Super_Management_Mayhem.Content.Animations;
using Super_Management_Mayhem.Content.Spritesheet;
using System;
using Transformable_Engine_v2.Engine.Animation.ColorAnimation;
using Transformable_Engine_v2.Engine.Animation.FrameAnimation;
using Transformable_Engine_v2.Engine.Animation.ScaleAnimation;
using Transformable_Engine_v2.Engine.Animation.Trajectory;
using Transformable_Engine_v2.Engine.GameObjects.Containers;
using Transformable_Engine_v2.Engine.GameObjects.Containers.Transformable_controls;
using Transformable_Engine_v2.Engine.Graphics;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Super_Management_Mayhem.Screens.Playing.Players.Hud
{
    public class Hud : Container
    {
        private readonly ImageContainer _attackIcon;
        private readonly Label _pointLabel;
        private readonly Label _timeLabel;

        private readonly ImageContainer[] _hearts;
        private readonly ImageContainer[] _heartsDead;

        private readonly ImageContainer[] _classes;

        private readonly ImageContainer _hourglass;

        private readonly Container _faceContainer;

        private TE_Vector2 _hudSize;

        public Hud(TE_Vector2 hudSize, string playerName, Color playerColor, int defaultHealth, int points)
        {
            _attackIcon = new ImageContainer {
                                            PositionGridBound = new TE_Vector2(0.5f, hudSize.Y - 0.5f),
                                            Sprite = UISheet.GetSprite(UISheet.AttackIcon.Sword),
                                            Origin = TE_Rectangle.Alignment.BottomLeft
                                        };

            _hudSize = hudSize;

            if(Playscreen.Controller.HasScore)
            {
                AddChildren(new ImageContainer {
                                               PositionGridBound = new TE_Vector2(hudSize.X - 0.5f, 0.5f),
                                               Sprite = UISheet.GetSprite(UISheet.Hud.Point),
                                               Origin = TE_Rectangle.Alignment.TopRight
                                           });

                _pointLabel = new Label(UISheet.GetInstance().GetSpriteAlphabet<UISheet.PointAlphabet>, points.ToString()) {
                                                                          PositionGridBound = new TE_Vector2(hudSize.X - 2, 1.75f),
                                                                          TextAlign = TE_Rectangle.Alignment.CenterRight,
                                                                          Origin = TE_Rectangle.Alignment.CenterMiddle
                                                                      };
                AddChildren(_pointLabel);
            }

            

            var playerIconContainer = new Container(0.5f, 0.5f);
            playerIconContainer.AddChildren(new ImageContainer {
                                                                   Sprite = UISheet.GetSprite(UISheet.PlayerIconContainer.Outline),
                                                                   Color = playerColor,
                                                                   Scale = new TE_Vector2(2, 2)
                                                               });
            playerIconContainer.AddChildren(new ImageContainer {
                                                                   Sprite = UISheet.GetSprite(UISheet.PlayerIconContainer.Inside),
                                                                   Scale = new TE_Vector2(2, 2)
                                                               });

            _faceContainer = new Container(2, 2);
            playerIconContainer.AddChildren(_faceContainer);

            var heartContainer = new Container(5, 0.5f);

            _hearts = new ImageContainer[defaultHealth];
            _heartsDead = new ImageContainer[defaultHealth];
            for(int i = 0; i < defaultHealth; i++)
            {
                _hearts[i] = new ImageContainer {
                                                    Sprite = UISheet.GetSprite(UISheet.Heart.Heart0),
                                                    PositionGridBound = new TE_Vector2(0 + i * 1, 0),
                                                };
                _hearts[i].AddAnimations(new FrameAnimation(new Hearts(), 0));

                _heartsDead[i] = new ImageContainer {
                                                    Sprite = UISheet.GetSprite(UISheet.Heart.Dead),
                                                    PositionGridBound = new TE_Vector2(0 + i * 1, 0),
                                                    Visible = false
                                                };
                heartContainer.AddChildren(_hearts[i], _heartsDead[i]);
            }


            if(Playscreen.Controller.HasTimeLimit)
            {
                _hourglass = new ImageContainer {
                                                PositionGridBound = new TE_Vector2(hudSize.X - 1.5f, hudSize.Y - 1.5f),
                                                Sprite = UISheet.GetSprite(UISheet.Hud.Hourglass),
                                                Origin = TE_Rectangle.Alignment.CenterMiddle
                                            };
                CallMethod(Playscreen.Controller.GameTimeLimit * 0.25f, () => AddHourglassAnimation(0.33f));
                CallMethod(Playscreen.Controller.GameTimeLimit * 0.5f, () => AddHourglassAnimation(0.66f));
                CallMethod(Playscreen.Controller.GameTimeLimit * 0.75f, () => AddHourglassAnimation(1));

                _timeLabel = new Label(UISheet.GetInstance().GetSpriteAlphabet<UISheet.PointAlphabet>, "") {
                                                                              PositionGridBound = new TE_Vector2(hudSize.X - 2.5f, hudSize.Y - 0.5f),
                                                                              TextAlign = TE_Rectangle.Alignment.BottomRight,
                                                                          };
                UpdateTimeLeft(Playscreen.Controller.GetRemainingTime());

                AddChildren(_hourglass, _timeLabel);
            }
            

            var nameLabel = new Label(UISheet.GetInstance().GetSpriteAlphabet<UISheet.LetterAlphabet>, playerName) {
                                                                                                             PositionGridBound = new TE_Vector2(11, 2.75f),
                                                                                                             //Use a lighter color for the name
                                                                                                             Color = (playerColor * 0.75f + Color.White * 0.25f),
                                                                                                             Scale = new TE_Vector2(2.25f, 2)
                                                                                                         };

            AddChildren(_attackIcon, heartContainer, playerIconContainer, nameLabel);


            Container classesContainer = new Container(5.75f, 3.5f);
            _classes = new ImageContainer[3];
            for (int i = 0; i < 3; i++)
            {
                _classes[i] = new ImageContainer
                              {
                                  PositionGridBound = new TE_Vector2(2 * i, 0),
                                  Sprite = ItemSheet.GetSprite(ItemSheet.Classes.Unknown),
                                  Origin = TE_Rectangle.Alignment.CenterMiddle,
                                  Scale = new TE_Vector2(1.5f, 1.5f)
                              };
            }
            classesContainer.AddChildren(_classes);

            AddChildren(classesContainer);

            AddChildren(new StartCountdown(2000) { PositionGridBound = hudSize * 0.5f });
        }

        public void ChangeFace(ImageContainer face)
        {
            _faceContainer.ClearChildren();

            _faceContainer.AddChildren(face);
        }

        public void TimesUp()
        {
            AddChildren(new TimeUp
                            {
                                PositionGridBound = _hudSize / 2
                            });
        }

        void UpdateTimeLeft(int timeLeft)
        {
            TimeSpan ts = new TimeSpan(0, 0, 0, 0, timeLeft);

            _timeLabel.SetText(ts.Minutes.ToString("0") + ":" + ts.Seconds.ToString("00"));
        }

        public override void FixedStepUpdate(TimeSpan gameTime)
        {
            if(Playscreen.Controller.HasTimeLimit)
                UpdateTimeLeft(Playscreen.Controller.GetRemainingTime());
            base.FixedStepUpdate(gameTime);
        }

        void AddHourglassAnimation(float level)
        {
            _hourglass.ClearAnimation();
            _hourglass.Scale = TE_Vector2.One;
            _hourglass.Color = Color.White;

            _hourglass.AddAnimations(new ScaleAnimation(new SinusTrajectory(), new TE_Vector2(0.75f + 0.75f * level, 0.75f + 0.75f * level), 1500 - 1000 * level, true, 0));
            _hourglass.AddAnimations(new ColorAnimation(new SinusTrajectory(), Color.White + (Color.Red - Color.White) * level, 1500 - 1000 * level, true, 0));
        }

        public void ChangeScore(int newScore, float _delta)
        {
            _pointLabel.ClearAnimation();
            _pointLabel.SetText(newScore.ToString());

            if(_delta >= 0)
            {
                _pointLabel.Color = Color.White;
                _pointLabel.Scale = new TE_Vector2(1.5f + 2 * _delta, 1.5f + 2 * _delta);
                _pointLabel.AddAnimations(new ScaleAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseOut), TE_Vector2.One, 300 + 1000 * _delta, false, 0));
            }
            else
            {
                _pointLabel.Color = Color.DarkRed;
                _pointLabel.Scale = TE_Vector2.One;
                _pointLabel.AddAnimations(new ColorAnimation(new LinearEasing(), Color.White, 500, false, 0));
            }
        }

        public void ChangeHealth(int newHealth)
        {
            for (int i = 0; i < newHealth; i++)
            {
                _hearts[i].Visible = true;
                _heartsDead[i].Visible = false;
            }
            for (int i = newHealth; i < _hearts.Length ; i++)
            {
                _hearts[i].Visible = false;
                _heartsDead[i].Visible = true;
            }
        }

        public void ChangeClass(ItemSheet.Classes[] currentClasses)
        {
            for (int i = 0; i < 3; i++)
            {
                _classes[i].Sprite = ItemSheet.GetSprite(currentClasses[i]);
            }
        }
    }
}